home *** CD-ROM | disk | FTP | other *** search
- /*
- * balls.c - Create a set of shiny spheres, with each sphere blooming sets of
- * 9 more spheres with 1/3rd radius. None of the spheres are clipped. A
- * square floor polygon is added. Three light sources.
- *
- * Version: 2.2 (11/17/87)
- * Author: Eric Haines, 3D/Eye, Inc.
- *
- * SIZE_FACTOR determines the number of objects output.
- * Total spheres = sum of n=0,SF of (9**SF).
- *
- * SIZE_FACTOR # spheres # squares
- * 1 10 1
- * 2 91 1
- * 3 820 1
- *
- * 4 7381 1
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include "def.h"
- #include "lib.h"
-
- #define OUTPUT_FORMAT OUTPUT_CURVES
- #define SIZE_FACTOR 3
-
- static COORD4 objset[9];
-
- /*
- * Output the parent sphere, then output the children of the sphere.
- * Uses global 'objset'.
- */
- void
- output_objset(char *txname, long depth, COORD4 *center, COORD4 *direction)
- {
- double angle;
- COORD4 axis, z_axis;
- COORD4 child_pt, child_dir;
- MATRIX mx;
- long num_vert;
- double scale;
-
- /* output sphere at location & radius defined by center */
- lib_output_sphere(center, txname);
-
- /* check if children should be generated */
- if ( depth > 0 ) {
- --depth ;
-
- /* rotation matrix to new axis from +Z axis */
- if ( direction->z >= 1.0 ) {
- /* identity matrix */
- lib_create_identity_matrix( mx ) ;
- }
- else if ( direction->z <= -1.0 ) {
- lib_create_rotate_matrix( mx, Y_AXIS, PI ) ;
- }
- else {
- SET_COORD( z_axis, 0.0, 0.0, 1.0 ) ;
- CROSS( axis, z_axis, (*direction) ) ;
- lib_normalize_coord3( &axis ) ;
- angle = acos( (double)DOT_PRODUCT( z_axis, (*direction) ) ) ;
- lib_create_axis_rotate_matrix( mx, &axis, angle ) ;
- }
-
- /* scale down location of new spheres */
- scale = center->w * (1.0 + direction->w ) ;
-
- for ( num_vert = 0 ; num_vert < 9 ; ++num_vert ) {
- lib_transform_coord( &child_pt, &objset[num_vert], mx ) ;
- child_pt.x = child_pt.x * scale + center->x ;
- child_pt.y = child_pt.y * scale + center->y ;
- child_pt.z = child_pt.z * scale + center->z ;
- /* scale down radius */
- child_pt.w = center->w * direction->w ;
- SUB3_COORD( child_dir, child_pt, (*center) ) ;
- child_dir.x /= scale ;
- child_dir.y /= scale ;
- child_dir.z /= scale ;
- child_dir.w = direction->w ;
- output_objset(txname, depth, &child_pt, &child_dir);
- }
- }
- }
-
- /* Create the set of 9 vectors needed to generate the sphere set. */
- /* Uses global 'objset' */
- void
- create_objset()
- {
- COORD4 axis, temp_pt, trio_dir[3] ;
- double dist ;
- MATRIX mx ;
- long num_set, num_vert ;
-
-
- dist = 1.0 / sqrt( (double)2.0 ) ;
-
- SET_COORD4( trio_dir[0], dist, dist, 0.0, 0.0 ) ;
- SET_COORD4( trio_dir[1], dist, 0.0, -dist, 0.0 ) ;
- SET_COORD4( trio_dir[2], 0.0, dist, -dist, 0.0 ) ;
-
- SET_COORD( axis, 1.0, -1.0, 0.0 ) ;
- lib_normalize_coord3( &axis ) ;
- lib_create_axis_rotate_matrix(
- mx,
- &axis,
- asin( (double) ( 2.0 / sqrt( (double)6.0 ) ) ) ) ;
-
- for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
- lib_transform_coord( &temp_pt, &trio_dir[num_vert], mx ) ;
- COPY_COORD( trio_dir[num_vert], temp_pt ) ;
- }
-
- for ( num_set = 0 ; num_set < 3 ; ++num_set ) {
- lib_create_rotate_matrix( mx, Z_AXIS, num_set*2.0*PI/3.0 ) ;
- for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
- lib_transform_coord( &objset[num_set*3+num_vert],
- &trio_dir[num_vert], mx ) ;
- }
- }
- }
-
- /* This is a reasonable good noise surface
- define txt000
- texture {
- noise surface {
- color white
- position_fn 1
- lookup_fn 1
- octaves 3
- turbulence 6
- ambient 0.2
- diffuse 0.8
- specular 0.3
- microfacet Reitz 5
- color_map(
- [0.0, 0.8, <1, 1, 1>, <0.6, 0.6, 0.6>]
- [0.8, 1.0, <0.6, 0.6, 0.6>, <0.1, 0.1, 0.1>])
- }
- }
- */
-
- void
- main(int argc, char *argv[])
- {
- COORD4 back_color, obj_color ;
- COORD4 backg[4], bvec, light ;
- COORD4 from, at, up, dir;
- COORD4 center_pt, direction ;
- double radius ;
- char *txname;
-
- /* set radius of sphere which would enclose entire object */
- radius = 1.0 ;
-
- /* output viewpoint */
- SET_COORD( from, 2.1, 1.3, 1.7 ) ;
- SET_COORD( at, 0.0, 0.0, 0.0 ) ;
- SET_COORD( up, 0.0, 0.0, 1.0 ) ;
- lib_output_viewpoint( &from, &at, &up, 45.0, 1.0, 1.0, 256, 256);
-
- /* output background color - UNC sky blue */
- SET_COORD( back_color, 0.078, 0.361, 0.753 ) ;
- lib_output_background_color( &back_color ) ;
-
- /* output light sources */
- SET_COORD( light, 4.0, 3.0, 2.0 ) ;
- lib_output_light( &light ) ;
- SET_COORD( light, 1.0, -4.0, 4.0 ) ;
- lib_output_light( &light ) ;
- SET_COORD( light, -3.0, 1.0, 5.0 ) ;
- lib_output_light( &light ) ;
-
- /* Output bounding slabs oriented along the coordinate axes */
- SET_COORD(dir, 1.0, 0.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 1.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 0.0, 1.0);
- lib_output_bounding_slab(&dir);
-
- /* output floor polygon - beige */
- SET_COORD( back_color, 1.0, 0.75, 0.33 ) ;
- txname = lib_output_color(&back_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0);
- bvec.x = bvec.y = radius * 12.0 ;
- bvec.z = -radius / 2.0 ;
- SET_COORD( backg[0], bvec.x, bvec.y, bvec.z ) ;
- SET_COORD( backg[1], -bvec.x, bvec.y, bvec.z ) ;
- SET_COORD( backg[2], -bvec.x, -bvec.y, bvec.z ) ;
- SET_COORD( backg[3], bvec.x, -bvec.y, bvec.z ) ;
- lib_output_polygon( 4, backg, txname);
-
- /* set up object color - off white */
- SET_COORD( obj_color, 1.0, 0.9, 0.7 ) ;
- txname = lib_output_color(&obj_color, 0.2, 0.8, 1.0, 10.0, 0.0, 0.0, 0.0);
-
- /* create set of spawned points */
- create_objset() ;
-
- /* compute and output object */
- SET_COORD4( center_pt, 0.0, 0.0, 0.0, radius / 2.0 ) ;
- SET_COORD4( direction, 0.0, 0.0, 1.0, 1.0/3.0 ) ;
- output_objset(txname, SIZE_FACTOR, ¢er_pt, &direction ) ;
- }
-